﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Abp.Application.Services.Dto;
using Abp.Collections.Extensions;
using Abp.Runtime.Caching;
using DevM.Development.DynamicInfomations.Dto;
using DevM.Development.Resources;
using DevM.Development.Resources.Dto;
using DevM.Sessions;
using Microsoft.AspNetCore.Http;

namespace DevM.Development.DynamicInfomations
{
    public class DynamicInfomationAppService : DevMAppServiceBase, IDynamicInfomationAppService
    {
        private readonly ISessionAppService sessionAppService;
        private readonly IHttpContextAccessor httpContextAccessor;
        private readonly ICacheManager cacheManager;
        private readonly ResourceManager resourceManager;
        private readonly DynamicInformationManager dynamicInformationManager;

        public DynamicInfomationAppService(ISessionAppService sessionAppService, IHttpContextAccessor httpContextAccessor, ICacheManager cacheManager, ResourceManager resourceManager, DynamicInformationManager dynamicInformationManager)
        {
            this.sessionAppService = sessionAppService;
            this.httpContextAccessor = httpContextAccessor;
            this.cacheManager = cacheManager;
            this.resourceManager = resourceManager;
            this.dynamicInformationManager = dynamicInformationManager;
        }

        public async Task<DynamicInfomationDto> AddDynamicInfomation(AddDynamicInfomationInput input)
        {
            var info = ObjectMapper.Map<DynamicInfomation>(input);

            var currentUserInfomation = await sessionAppService.GetCurrentLoginInformations();
            info.CreationTime = DateTime.Now;
            info.CreatorUserId = currentUserInfomation.User?.Id ?? 0;
            info.TenantId = currentUserInfomation.Tenant?.Id;
            info = await dynamicInformationManager.AddDynamicInfomation(info);

            var dynamicInfoResources = input.ResourceIds.Select(r => new RecordResource
            {
                CreationTime = DateTime.Now,
                CreatorUserId = info.CreatorUserId,
                TenantId = info.TenantId,
                ResourceId = r,
                RecoordId = info.Id,
                RecoordType = typeof(DynamicInfomation).FullName
            }).ToList();
            await resourceManager.AddRecordResource(dynamicInfoResources);


            return ObjectMapper.Map<DynamicInfomationDto>(info);
        }

        public async Task DeleteDynamicInfomation(EntityDto<long> infomationId)
        {
            var currentUserInfomation = await sessionAppService.GetCurrentLoginInformations();
            await dynamicInformationManager.DeleteDynamicInfomation(currentUserInfomation.User?.Id ?? 0, infomationId.Id);
            var infoResources = await dynamicInformationManager.GetInformationResourcesByInformationId(infomationId.Id);
            if (infoResources != null && infoResources.Count() > 0)
            {
                await dynamicInformationManager.DeleteInformationResource(infoResources.Select(r => r.Id).ToArray());
            }
        }


        public async Task DeleteInfomationResource(EntityDto<long> infomationResourceId)
        {
            await resourceManager.DeleteRecordResource(typeof(DynamicInfomation).FullName, infomationResourceId.Id);
        }

        public async Task<PageOutput<DynamicInfomationDto>> GetDynamicInfomations(GetDynamicInfomationListInput input)
        {
            var dataset = dynamicInformationManager.DynamicInfomations.WhereIf(input.ProjectId > 0, di => di.ProjectId == input.ProjectId).WhereIf(input.InformationId > 0, d => d.Id == input.InformationId).OrderByDescending(r => r.Id);
            var items = dataset.Skip(input.SkipCount).Take(input.MaxResultCount).ToList();
            var total = dataset.Count();
            var resultItems = ObjectMapper.Map<List<DynamicInfomationDto>>(items);
            resultItems.ForEach(di =>
            {
                di.TotalResources = resourceManager.RecordResources.Where(r => r.RecoordId == di.Id&&r.RecoordType==typeof(DynamicInfomation).FullName).Count();
            });
            return new PageOutput<DynamicInfomationDto>
            {
                Items = resultItems,
                TotalCount = total
            };
        }

        public async Task<List<InfomationResourceDto>> GetInfomationResourcesByInfomationId(EntityDto<long> infomationId)
        {
            var recordResources = await resourceManager.GetRecordResources(typeof(DynamicInfomation).FullName, infomationId.Id);
            var resourcesDto = recordResources.Select(rr => new InfomationResourceDto { Id = rr.Id, DynamicInfomationId = rr.RecoordId, ResourceId = rr.ResourceId }).ToList();
            resourcesDto.ForEach(async r =>
            {
                r.Resource = ObjectMapper.Map<ResourceDto>((await resourceManager.GetResourceListById(r.ResourceId)).FirstOrDefault());
            });
            return resourcesDto;

        }

    }
}
